#include "InputManager.h"

InputManager::InputManager() : mouse(0), keyboard(0), inputManager(0)
{
}

void InputManager::initialise(Ogre::RenderWindow *rw)
{
	OIS::ParamList pl;
	size_t windowHnd = 0;
	std::ostringstream windowHndStr;
	rw->getCustomAttribute("WINDOW", &windowHnd);
	windowHndStr << windowHnd;
	pl.insert(std::make_pair(std::string("WINDOW"),windowHndStr.str()));
	inputManager = OIS::InputManager::createInputSystem(pl);
	keyboard = static_cast<OIS::Keyboard*>(inputManager->createInputObject(OIS::OISKeyboard,true));
	mouse = static_cast<OIS::Mouse*>(inputManager->createInputObject(OIS::OISMouse,true));
	keyboard->setEventCallback(this);
	mouse->setEventCallback(this);
	setWindowSize(rw->getWidth(), rw->getHeight());
    createKeyMap();
}

void InputManager::capture()
{
	if (mouse) mouse->capture();
	if (keyboard) keyboard->capture();
}

void InputManager::setWindowSize(int w, int h)
{
	if (mouse)
	{
		const OIS::MouseState &ms = mouse->getMouseState();
		ms.width = w;
		ms.height = h;
	}
	width = w;
	height = h;
}

bool InputManager::addKeyListener(OIS::KeyListener *kl, std::string name)
{
	if (keyListeners[name]==NULL)
	{
		keyListeners[name]=kl;
		return true;
	}
	else return false;
}

bool InputManager::addMouseListener(OIS::MouseListener *ml, std::string name)
{
	if (mouseListeners[name]==NULL)
	{
		mouseListeners[name]=ml;
		return true;
	}
	else return false;
}

bool InputManager::removeKeyListener(std::string name)
{
	return keyListeners.erase(name)!=0;
}

bool InputManager::removeMouseListener(std::string name)
{
	return mouseListeners.erase(name)!=0;
}

void InputManager::removeAllKeyListeners()
{
	keyListeners.clear();
}

void InputManager::removeAllMouseListeners()
{
	mouseListeners.clear();
}

bool InputManager::releaseMouse()
{
	if (mouse)
	{
		inputManager->destroyInputObject(mouse);
		mouse = 0;
		return true;
	}
	else return false;
}

bool InputManager::grabMouse()
{
	if (!mouse)
	{
		mouse = static_cast<OIS::Mouse*>(inputManager->createInputObject(OIS::OISMouse, true));
		mouse->setEventCallback(this);
		setWindowSize(width,height);
		return true;
	}
	else return false;
}

bool InputManager::keyPressed(const OIS::KeyEvent &evt)
{
	for (std::map<std::string, OIS::KeyListener*>::iterator it = keyListeners.begin(); it != keyListeners.end(); it++)
		if (!it->second->keyPressed(evt)) return false;
	return true;
}

bool InputManager::keyReleased(const OIS::KeyEvent &evt)
{
	for (std::map<std::string, OIS::KeyListener*>::iterator it = keyListeners.begin(); it != keyListeners.end(); it++)
		if (!it->second->keyReleased(evt)) return false;
	return true;
}
bool InputManager::mouseMoved(const OIS::MouseEvent &evt)
{
	for (std::map<std::string, OIS::MouseListener*>::iterator it = mouseListeners.begin(); it != mouseListeners.end(); it++)
		if (!it->second->mouseMoved(evt)) return false;
	return true;
}
bool InputManager::mousePressed(const OIS::MouseEvent &evt, OIS::MouseButtonID id)
{
	for (std::map<std::string, OIS::MouseListener*>::iterator it = mouseListeners.begin(); it != mouseListeners.end(); it++)
		if (!it->second->mousePressed(evt,id)) return false;
	return true;
}
bool InputManager::mouseReleased(const OIS::MouseEvent &evt, OIS::MouseButtonID id)
{
	for (std::map<std::string, OIS::MouseListener*>::iterator it = mouseListeners.begin(); it != mouseListeners.end(); it++)
		if (!it->second->mouseReleased(evt,id)) return false;
	return true;
}

OIS::KeyCode InputManager::getKeyCode(std::string name)
{
    return keys[name];
}

void InputManager::createKeyMap()
{
   keys["KC_UNASSIGNED"]= OIS::KC_UNASSIGNED;
   keys["KC_ESCAPE"]= OIS::KC_ESCAPE;
   keys["KC_1"]= OIS::KC_1;
   keys["KC_2"]= OIS::KC_2;
   keys["KC_3"]= OIS::KC_3;
   keys["KC_4"]= OIS::KC_4;
   keys["KC_5"]= OIS::KC_5;
   keys["KC_6"]= OIS::KC_6;
   keys["KC_7"]= OIS::KC_7;
   keys["KC_8"]= OIS::KC_8;
   keys["KC_9"]= OIS::KC_9;
   keys["KC_0"]= OIS::KC_0;
   keys["KC_MINUS"]= OIS::KC_MINUS;
   keys["KC_EQUALS"]= OIS::KC_EQUALS;
   keys["KC_BACK"]= OIS::KC_BACK;
   keys["KC_TAB"]= OIS::KC_TAB;
   keys["KC_Q"]= OIS::KC_Q;
   keys["KC_W"]= OIS::KC_W;
   keys["KC_E"]= OIS::KC_E;
   keys["KC_R"]= OIS::KC_R;
   keys["KC_T"]= OIS::KC_T;
   keys["KC_Y"]= OIS::KC_Y;
   keys["KC_U"]= OIS::KC_U;
   keys["KC_I"]= OIS::KC_I;
   keys["KC_O"]= OIS::KC_O;
   keys["KC_P"]= OIS::KC_P;
   keys["KC_LBRACKET"]= OIS::KC_LBRACKET;
   keys["KC_RBRACKET"]= OIS::KC_RBRACKET;
   keys["KC_RETURN"]= OIS::KC_RETURN;
   keys["KC_LCONTROL"]= OIS::KC_LCONTROL;
   keys["KC_A"]= OIS::KC_A;
   keys["KC_S"]= OIS::KC_S;
   keys["KC_D"]= OIS::KC_D;
   keys["KC_F"]= OIS::KC_F;
   keys["KC_G"]= OIS::KC_G;
   keys["KC_H"]= OIS::KC_H;
   keys["KC_J"]= OIS::KC_J;
   keys["KC_K"]= OIS::KC_K;
   keys["KC_L"]= OIS::KC_L;
   keys["KC_SEMICOLON"]= OIS::KC_SEMICOLON;
   keys["KC_APOSTROPHE"]= OIS::KC_APOSTROPHE;
   keys["KC_GRAVE"]= OIS::KC_GRAVE;
   keys["KC_LSHIFT"]= OIS::KC_LSHIFT;
   keys["KC_BACKSLASH"]= OIS::KC_BACKSLASH;
   keys["KC_Z"]= OIS::KC_Z;
   keys["KC_X"]= OIS::KC_X;
   keys["KC_C"]= OIS::KC_C;
   keys["KC_V"]= OIS::KC_V;
   keys["KC_B"]= OIS::KC_B;
   keys["KC_N"]= OIS::KC_N;
   keys["KC_M"]= OIS::KC_M;
   keys["KC_COMMA"]= OIS::KC_COMMA;
   keys["KC_PERIOD"]= OIS::KC_PERIOD;
   keys["KC_SLASH"]= OIS::KC_SLASH;
   keys["KC_RSHIFT"]= OIS::KC_RSHIFT;
   keys["KC_MULTIPLY"]= OIS::KC_MULTIPLY;
   keys["KC_LMENU"]= OIS::KC_LMENU;
   keys["KC_SPACE"]= OIS::KC_SPACE;
   keys["KC_CAPITAL"]= OIS::KC_CAPITAL;
   keys["KC_F1"]= OIS::KC_F1;
   keys["KC_F2"]= OIS::KC_F2;
   keys["KC_F3"]= OIS::KC_F3;
   keys["KC_F4"]= OIS::KC_F4;
   keys["KC_F5"]= OIS::KC_F5;
   keys["KC_F6"]= OIS::KC_F6;
   keys["KC_F7"]= OIS::KC_F7;
   keys["KC_F8"]= OIS::KC_F8;
   keys["KC_F9"]= OIS::KC_F9;
   keys["KC_F10"]= OIS::KC_F10;
   keys["KC_NUMLOCK"]= OIS::KC_NUMLOCK;
   keys["KC_SCROLL"]= OIS::KC_SCROLL;
   keys["KC_NUMPAD7"]= OIS::KC_NUMPAD7;
   keys["KC_NUMPAD8"]= OIS::KC_NUMPAD8;
   keys["KC_NUMPAD9"]= OIS::KC_NUMPAD9;
   keys["KC_SUBTRACT"]= OIS::KC_SUBTRACT;
   keys["KC_NUMPAD4"]= OIS::KC_NUMPAD4;
   keys["KC_NUMPAD5"]= OIS::KC_NUMPAD5;
   keys["KC_NUMPAD6"]= OIS::KC_NUMPAD6;
   keys["KC_ADD"]= OIS::KC_ADD;
   keys["KC_NUMPAD1"]= OIS::KC_NUMPAD1;
   keys["KC_NUMPAD2"]= OIS::KC_NUMPAD2;
   keys["KC_NUMPAD3"]= OIS::KC_NUMPAD3;
   keys["KC_NUMPAD0"]= OIS::KC_NUMPAD0;
   keys["KC_DECIMAL"]= OIS::KC_DECIMAL;
   keys["KC_RCONTROL"]= OIS::KC_RCONTROL;
   keys["KC_DIVIDE"]= OIS::KC_DIVIDE;
   keys["KC_SYSRQ"]= OIS::KC_SYSRQ;
   keys["KC_RMENU"]= OIS::KC_RMENU;
   keys["KC_PAUSE"]= OIS::KC_PAUSE;
   keys["KC_HOME"]= OIS::KC_HOME;
   keys["KC_UP"]= OIS::KC_UP;
   keys["KC_PGUP"]= OIS::KC_PGUP;
   keys["KC_LEFT"]= OIS::KC_LEFT;
   keys["KC_RIGHT"]= OIS::KC_RIGHT;
   keys["KC_END"]= OIS::KC_END;
   keys["KC_DOWN"]= OIS::KC_DOWN;
   keys["KC_PGDOWN"]= OIS::KC_PGDOWN;
   keys["KC_INSERT"]= OIS::KC_INSERT;
   keys["KC_DELETE"]= OIS::KC_DELETE;
   keys["KC_LWIN"]= OIS::KC_LWIN;
   keys["KC_RWIN"]= OIS::KC_RWIN;
   keys["KC_APPS"]= OIS::KC_APPS;
}